package com.adcc.swingui.base;

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;

import org.apache.log4j.Logger;

import com.adcc.cs.util.CommonUtil;
import com.jidesoft.action.CommandBarFactory;
import com.jidesoft.swing.JideSplitButton;
/**
 * 状态栏按钮超类
 * 工具栏内部需要相互识别联动
 * 有时也需要联动菜单
 * 依赖关系相当比较复杂
 * 尽量少的依赖，一旦被具体依赖了，就不太容易通过配置来动态增减工具按钮
 * @author charlie
 *
 */
public abstract class DefaultToolBar extends CommandBarFactory {
	private static Logger logger = Logger.getLogger(DefaultToolBar.class);
	/**
	 * 状态栏map
	 */
	protected static Map<String, DefaultToolBar> toolMap = new HashMap<String, DefaultToolBar>();
	/**
	 * 菜单子类map， 需要通过父类查找子类
	 */
	protected Map<String, AbstractButton> toolChildMap = new HashMap<String, AbstractButton>();
	/**
	 * 状态栏源
	 */
	protected JComponent sourceComp ;
	/**
	 * swing框架容器
	 */
	protected Container container;
	/**
	 * 名称
	 */
	protected String name = this.getClass().getName();
	public DefaultToolBar(Container container) {
		this.container = container;
	}
	/**
	 * 需要被重写工具构造器
	 * @return
	 */
	protected abstract JComponent build();
	/**
	 * 国际化
	 */
	protected abstract void i18n();
	/**
	 * 添加子节点，并且加入对应事件，如果不想要事件，name设置成null
	 * @param parent
	 * @param chlid
	 * @param name
	 */
	protected void addChildItem(final AbstractButton parent, final AbstractButton chlid, 
			final String name) {
		parent.add(chlid);
		//name为空代表没有操作菜单，只是容器，不放在缓存map里面
		if(name != null) {
			chlid.setName(name);
			//反射注册事件
			chlid.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					CommonUtil.invoke(DefaultToolBar.this, name, null);
				}
			});
			if(toolChildMap.containsKey(name)) {
				logger.warn(name + "子工具栏缓存map对象已经存在");
			}
			toolChildMap.put(name, chlid);
		}
	}
	/**
	 * 鼠标左键事件
	 */
	protected abstract void addMouseListener();
	/**
	 * 外部调用工具构造器
	 * @param name 控件名称
	 * @param threadLis 线程监听器
	 * @return
	 */
	public JComponent buildButton(String name,final boolean threadLis) {
		this.sourceComp = build();
		i18n();
		//添加事件
		if(this.sourceComp instanceof AbstractButton) {
			//按钮类操作
			((AbstractButton)this.sourceComp).addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					doAction(threadLis);
				}
			});
		} else if(this.sourceComp instanceof JComboBox) {
			//选择框类操作
			((JComboBox)this.sourceComp).addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					doAction(threadLis);
				}
			});
		} else {
			//其他操作
			this.sourceComp.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseClicked(MouseEvent e) {
					doAction(threadLis);
				}
	        });
		}
		if(toolMap.containsKey(name)) {
			logger.warn(name + "工具栏缓存map对象已经存在");
		}
		toolMap.put(name, this);
		return this.sourceComp;
	}
	/**
	 * 事件响应
	 * @param threadLis
	 */
	private void doAction(boolean threadLis) {
		//如果菜单不可编辑，停止响应
		if(!sourceComp.isEnabled()) {
			return;
		}
		//如果弹出菜单，就停止响应
		if(sourceComp instanceof JideSplitButton) {
			JideSplitButton but = (JideSplitButton)sourceComp;
			if(but.isPopupMenuVisible()) {
				return;
			}
		}
		//鼠标左键事件才响应
			if(threadLis) {
				//线程执行,这种线程没有管理起来，可能会有重复执行的情况
				new Thread(new Runnable() {
					public void run() {
						//执行方法前，设置按钮不可操作
						sourceComp.setEnabled(false);
						try {
							addMouseListener();
						} catch (Exception e) {
							e.printStackTrace();
						}
						//执行方法后，设置按钮可操作
						sourceComp.setEnabled(true);
					}
				}).start();
			} else {
				addMouseListener();
			}
	}
	
	/**
	 * 外部调用工具构造器
	 * @param name
	 * @return
	 */
	public JComponent buildButton(String name) {
		return buildButton(name, false);
	}
	
	/**
	 * 创建复选框菜单
	 * @param name  名称
	 * @param text  显示文本
	 * @return
	 */
	protected static JCheckBoxMenuItem createCheckBoxMenuItem(String name, String text) {
		JCheckBoxMenuItem item= new JCheckBoxMenuItem(text);
		item.setName(name);
		return item;
	}
	
	/**
	 * 创建单选框菜单
	 * @param name  名称
	 * @param text  显示文本
	 * @return
	 */
	protected static JRadioButtonMenuItem createRadioButtonMenuItem(String name, String text, ButtonGroup group) {
		JRadioButtonMenuItem item= new JRadioButtonMenuItem(text);
		item.setName(name);
		group.add(item);
		return item;
	}
	
	/**
	 * 获取选中节点的名称，名称是不变的，值是经过国际化的
	 */
	public List<String> getSelectedItemName(JMenuItem[] items) {
		List<String> list = new ArrayList<String>();
		for (int i = 0; i < items.length; i++) {
			if(items[i].isSelected()) {
				list.add(items[i].getName());
			}
		}
		return list;
	}
	
	/**
	 * 获取源
	 * @return
	 */
	public JComponent getSourceComp() {
		return sourceComp;
	}
	
	/**
	 * 工具集合
	 * @return
	 */
	public static Map<String, DefaultToolBar> getToolMap() {
		return toolMap;
	}
}
